/**
 * ThresholdFilterControl.java
 * 
 * @date: 2012-02-09
 * @author: Xiaoyu Guo (MUN# 200982155)
 * This file is part of the course project for COMP 6752, 
 * Application of Computer Graphics. All the file is written
 * by myself.
 */
package mun.cs6752.project.filter.threshold;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import mun.cs6752.project.filter.abstractClasses.AbstractImageFilterControl;
import mun.cs6752.project.filter.interfaces.IImageFilter;
import mun.cs6752.project.filter.interfaces.IImageFilterParameter;
import mun.cs6752.project.filter.interfaces.IImageProvider;

/**
 * @author Xiaoyu Guo
 *
 */
public class ThresholdFilterControl extends AbstractImageFilterControl {
    private static final long serialVersionUID = -1613128237557780060L;
    
    private int thresholdGrey;
    private int thresholdRed, thresholdGreen, thresholdBlue;
    private boolean isGrey;

    private JSpinner spGrey;
    private JSlider sldGrey;
    private JRadioButton rdbtnColorThreshold;
    private JSlider sldRed;
    private JSpinner spRed;
    private JSlider sldGreen;
    private JSpinner spGreen;
    private JSlider sldBlue;
    private JSpinner spBlue;
    private JRadioButton rdbtnGreyThreshold;

    private void setIsGrey(boolean value) {
        isGrey = value;
        
        rdbtnGreyThreshold.setSelected(value);

        sldGrey.setEnabled(value);
        spGrey.setEnabled(value);
        
        sldRed.setEnabled(!value);
        spRed.setEnabled(!value);
        sldGreen.setEnabled(!value);
        spGreen.setEnabled(!value);
        sldBlue.setEnabled(!value);
        spBlue.setEnabled(!value);
    }
    
    private void setThresholdGrey(int value){
        this.thresholdGrey = value;
        
        sldGrey.setValue(value);
        spGrey.setValue(value);
    }
    
    private void setThresholdRed(int value){
        this.thresholdRed = value;
        
        sldRed.setValue(value);
        spRed.setValue(value);
    }
    
    private void setThresholdGreen(int value){
        this.thresholdGreen = value;
        
        sldGreen.setValue(value);
        spGreen.setValue(value);
    }
    
    private void setThresholdBlue(int value){
        this.thresholdBlue = value;
        
        sldBlue.setValue(value);
        spBlue.setValue(value);
    }
    
    /**
     * @param provider
     * @param filter
     */
    public ThresholdFilterControl(IImageProvider provider, IImageFilter filter) {
        super(provider, filter);
    }
    
    @Override
    protected void initUI(){
        super.initUI();
        
        JPanel pnlControls = new JPanel();
        GridBagLayout gbl_pnlControls = new GridBagLayout();
        gbl_pnlControls.columnWidths = new int[]{80, 112, 60, 0, 0};
        gbl_pnlControls.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0};
        gbl_pnlControls.columnWeights = new double[]{1.0, 1.0, 1.0, 0.5, 1.0};
        gbl_pnlControls.rowWeights = new double[]{1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0};
        pnlControls.setLayout(gbl_pnlControls);
        add(pnlControls, BorderLayout.CENTER);
        
        this.rdbtnGreyThreshold = new JRadioButton("Grey");
        rdbtnGreyThreshold.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(rdbtnGreyThreshold.isSelected()){
                    setIsGrey(true);
                    preview();
                }
            }
        });
        GridBagConstraints gbc_rdbtnGreyThreshold = new GridBagConstraints();
        gbc_rdbtnGreyThreshold.anchor = GridBagConstraints.WEST;
        gbc_rdbtnGreyThreshold.insets = new Insets(0, 0, 5, 5);
        gbc_rdbtnGreyThreshold.gridx = 0;
        gbc_rdbtnGreyThreshold.gridy = 0;
        pnlControls.add(rdbtnGreyThreshold, gbc_rdbtnGreyThreshold);
        
        JLabel lblThresholdGrey = new JLabel("Grey");
        GridBagConstraints gbc_lblThresholdGrey = new GridBagConstraints();
        gbc_lblThresholdGrey.anchor = GridBagConstraints.EAST;
        gbc_lblThresholdGrey.insets = new Insets(0, 0, 5, 5);
        gbc_lblThresholdGrey.gridx = 0;
        gbc_lblThresholdGrey.gridy = 1;
        pnlControls.add(lblThresholdGrey, gbc_lblThresholdGrey);
        
        this.sldGrey = new JSlider();
        sldGrey.setMaximum(255);
        sldGrey.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                setThresholdGrey((int)sldGrey.getValue());
                
                if(!sldGrey.getValueIsAdjusting()){
                    preview();
                }
            }
        });
        GridBagConstraints gbc_sldGrey = new GridBagConstraints();
        gbc_sldGrey.fill = GridBagConstraints.HORIZONTAL;
        gbc_sldGrey.insets = new Insets(0, 0, 5, 5);
        gbc_sldGrey.gridx = 1;
        gbc_sldGrey.gridy = 1;
        pnlControls.add(sldGrey, gbc_sldGrey);
        
        this.spGrey = new JSpinner();
        spGrey.setModel(new SpinnerNumberModel(127, 0, 255, 1));
        spGrey.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                setThresholdGrey(((SpinnerNumberModel)spGrey.getModel()).getNumber().intValue());
            }
        });
        GridBagConstraints gbc_spGrey = new GridBagConstraints();
        gbc_spGrey.fill = GridBagConstraints.HORIZONTAL;
        gbc_spGrey.insets = new Insets(0, 0, 5, 5);
        gbc_spGrey.gridx = 2;
        gbc_spGrey.gridy = 1;
        pnlControls.add(spGrey, gbc_spGrey);
        
        this.rdbtnColorThreshold = new JRadioButton("Color");
        rdbtnColorThreshold.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if(rdbtnColorThreshold.isSelected()){
                    setIsGrey(false);
                    preview();
                }
            }
        });
        GridBagConstraints gbc_rdbtnColorThreshold = new GridBagConstraints();
        gbc_rdbtnColorThreshold.anchor = GridBagConstraints.WEST;
        gbc_rdbtnColorThreshold.insets = new Insets(0, 0, 5, 5);
        gbc_rdbtnColorThreshold.gridx = 0;
        gbc_rdbtnColorThreshold.gridy = 2;
        pnlControls.add(rdbtnColorThreshold, gbc_rdbtnColorThreshold);
        
        JLabel lblThresholdRed = new JLabel("Red");
        GridBagConstraints gbc_lblThresholdRed = new GridBagConstraints();
        gbc_lblThresholdRed.anchor = GridBagConstraints.EAST;
        gbc_lblThresholdRed.insets = new Insets(0, 0, 5, 5);
        gbc_lblThresholdRed.fill = GridBagConstraints.VERTICAL;
        gbc_lblThresholdRed.gridx = 0;
        gbc_lblThresholdRed.gridy = 3;
        pnlControls.add(lblThresholdRed, gbc_lblThresholdRed);
        
        this.sldRed = new JSlider();
        sldRed.setMaximum(255);
        sldRed.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                setThresholdRed((int)sldRed.getValue());
                
                if(!sldRed.getValueIsAdjusting()){
                    preview();
                }
            }
        });
        GridBagConstraints gbc_sldRed = new GridBagConstraints();
        gbc_sldRed.fill = GridBagConstraints.HORIZONTAL;
        gbc_sldRed.insets = new Insets(0, 0, 5, 5);
        gbc_sldRed.gridx = 1;
        gbc_sldRed.gridy = 3;
        pnlControls.add(sldRed, gbc_sldRed);
        
        this.spRed = new JSpinner();
        spRed.setModel(new SpinnerNumberModel(127, 0, 255, 1));
        spRed.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                setThresholdRed(((SpinnerNumberModel)spRed.getModel()).getNumber().intValue());
            }
        });
        GridBagConstraints gbc_spRed = new GridBagConstraints();
        gbc_spRed.fill = GridBagConstraints.HORIZONTAL;
        gbc_spRed.insets = new Insets(0, 0, 5, 5);
        gbc_spRed.gridx = 2;
        gbc_spRed.gridy = 3;
        pnlControls.add(spRed, gbc_spRed);
        
        JLabel lblThresholdGreen = new JLabel("Green");
        GridBagConstraints gbc_lblThresholdGreen = new GridBagConstraints();
        gbc_lblThresholdGreen.anchor = GridBagConstraints.EAST;
        gbc_lblThresholdGreen.insets = new Insets(0, 0, 5, 5);
        gbc_lblThresholdGreen.gridx = 0;
        gbc_lblThresholdGreen.gridy = 4;
        pnlControls.add(lblThresholdGreen, gbc_lblThresholdGreen);
        
        this.sldGreen = new JSlider();
        sldGreen.setMaximum(255);
        sldGreen.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                setThresholdGreen((int)sldGreen.getValue());
                
                if(!sldGreen.getValueIsAdjusting()){
                    preview();
                }
            }
        });
        GridBagConstraints gbc_sldGreen = new GridBagConstraints();
        gbc_sldGreen.fill = GridBagConstraints.HORIZONTAL;
        gbc_sldGreen.insets = new Insets(0, 0, 5, 5);
        gbc_sldGreen.gridx = 1;
        gbc_sldGreen.gridy = 4;
        pnlControls.add(sldGreen, gbc_sldGreen);
        
        this.spGreen = new JSpinner();
        spGreen.setModel(new SpinnerNumberModel(127, 0, 255, 1));
        spGreen.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                setThresholdGreen(((SpinnerNumberModel)spGreen.getModel()).getNumber().intValue());
            }
        });
        GridBagConstraints gbc_spGreen = new GridBagConstraints();
        gbc_spGreen.fill = GridBagConstraints.HORIZONTAL;
        gbc_spGreen.insets = new Insets(0, 0, 5, 5);
        gbc_spGreen.gridx = 2;
        gbc_spGreen.gridy = 4;
        pnlControls.add(spGreen, gbc_spGreen);
        
        JLabel lblThresholdBlue = new JLabel("Blue");
        GridBagConstraints gbc_lblThresholdBlue = new GridBagConstraints();
        gbc_lblThresholdBlue.insets = new Insets(0, 0, 0, 5);
        gbc_lblThresholdBlue.anchor = GridBagConstraints.EAST;
        gbc_lblThresholdBlue.gridx = 0;
        gbc_lblThresholdBlue.gridy = 5;
        pnlControls.add(lblThresholdBlue, gbc_lblThresholdBlue);
        
        this.sldBlue = new JSlider();
        sldBlue.setMaximum(255);
        sldBlue.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                setThresholdBlue((int)sldBlue.getValue());
                
                if(!sldBlue.getValueIsAdjusting()){
                    preview();
                }
            }
        });
        GridBagConstraints gbc_sldBlue = new GridBagConstraints();
        gbc_sldBlue.fill = GridBagConstraints.HORIZONTAL;
        gbc_sldBlue.insets = new Insets(0, 0, 0, 5);
        gbc_sldBlue.gridx = 1;
        gbc_sldBlue.gridy = 5;
        pnlControls.add(sldBlue, gbc_sldBlue);
        
        this.spBlue = new JSpinner();
        spBlue.setModel(new SpinnerNumberModel(127, 0, 255, 1));
        spBlue.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                setThresholdBlue(((SpinnerNumberModel)spBlue.getModel()).getNumber().intValue());
            }
        });
        GridBagConstraints gbc_spBlue = new GridBagConstraints();
        gbc_spBlue.insets = new Insets(0, 0, 0, 5);
        gbc_spBlue.fill = GridBagConstraints.HORIZONTAL;
        gbc_spBlue.gridx = 2;
        gbc_spBlue.gridy = 5;
        pnlControls.add(spBlue, gbc_spBlue);
        
        ButtonGroup thresholdMethod = new ButtonGroup();
        thresholdMethod.add(rdbtnGreyThreshold);
        thresholdMethod.add(rdbtnColorThreshold);
    }
    
    @Override
    protected void initValue(){
        super.initValue();
        
        setIsGrey(true);
        setThresholdGrey(127);
        
        setThresholdRed(127);
        setThresholdGreen(127);
        setThresholdBlue(127);
    }

    /* (non-Javadoc)
     * @see mun.cs6752.project.filter.interfaces.IImageFilterControl#getParameter()
     */
    @Override
    public IImageFilterParameter getParameter() {
        if(this.isGrey){
            return new ThresholdFilterParameter(thresholdGrey);
        } else {
            return new ThresholdFilterParameter(thresholdRed, thresholdGreen, thresholdBlue);
        }
    }

}
